CloudCompare 您所在的位置:网站首页 MATLAB 点云误差显示 CloudCompare

CloudCompare

2023-11-28 13:17| 来源: 网络整理| 查看: 265

目录 1.二次曲面拟合2.参考文献3.操作流程4.完整操作5.算法源码6.相关代码 在这里插入图片描述

本文由CSDN点云侠原创,原文链接。爬虫网站自重。博客长期更新,本文最新更新时间为:2023年8月6日。

1.二次曲面拟合

  二次曲面方程如下: z ( x , y ) = a x 2 + b x y + c y 2 + d x + e y + f (1) z(x,y)=ax^2+bxy+cy^2+dx+ey+f \tag{1} z(x,y)=ax2+bxy+cy2+dx+ey+f(1) 采用最小二乘法拟合局部二次曲面,建立目标函数为: z = ∑ i = 0 k [ z ( x i , y i ) − z i ] 2 (2) z=\sum_{i=0}^{k}[z(x_i,y_i)-z_i]^2 \tag{2} z=i=0∑k​[z(xi​,yi​)−zi​]2(2) 联立式( 1) 和式( 2) ,对各项系数求偏导,并令偏导数等于零,得到线性方程组,见式( 3) ,求解线性方程组,得到局部二次拟合曲面方程。 [ ∑ i = 0 k x i 4 ∑ i = 0 k x i 3 y i ∑ i = 0 k x i 2 y i ∑ i = 0 k x i 3 ∑ i = 0 k x i 2 y i ∑ i = 0 k x i 2 ∑ i = 0 k x i 3 y i ∑ i = 0 k x i 2 y i 2 ∑ i = 0 k x i y i 3 ∑ i = 0 k x i 2 y i ∑ i = 0 k x i y i 2 ∑ i = 0 k x i y i ∑ i = 0 k x i 2 y i 2 ∑ i = 0 k x i y i 3 ∑ i = 0 k y i 4 ∑ i = 0 k x i y i 2 ∑ i = 0 k y i 3 ∑ i = 0 k y i 2 ∑ i = 0 k x i 3 ∑ i = 0 k x i 2 y i ∑ i = 0 k x i y i 2 ∑ i = 0 k x i 2 ∑ i = 0 k x i y i ∑ i = 0 k x i ∑ i = 0 k x i 2 y i ∑ i = 0 k x i y i 2 ∑ i = 0 k y i 3 ∑ i = 0 k x i y i ∑ i = 0 k y i 2 ∑ i = 0 k y i ∑ i = 0 k x i 2 ∑ i = 0 k x i y i ∑ i = 0 k y i 2 ∑ i = 0 k x i ∑ i = 0 k y i ∑ i = 0 k 1 ] [ a b c d e f ] = [ ∑ i = 0 k z i x i 2 ∑ i = 0 k z i x i y i ∑ i = 0 k z i y i 2 ∑ i = 0 k z i x i ∑ i = 0 k z i y i ∑ i = 0 k z i ] (3) \left[ \begin{matrix} \sum_{i=0}^{k}x_i^4 & \sum_{i=0}^{k}x_i^3y_i & \sum_{i=0}^{k}x_i^2y_i& \sum_{i=0}^{k}x_i^3& \sum_{i=0}^{k}x_i^2y_i& \sum_{i=0}^{k}x_i^2\\ \sum_{i=0}^{k}x_i^3y_i & \sum_{i=0}^{k}x_i^2y_i^2 & \sum_{i=0}^{k}x_iy_i^3 & \sum_{i=0}^{k}x_i^2y_i& \sum_{i=0}^{k}x_iy_i^2& \sum_{i=0}^{k}x_iy_i\\ \sum_{i=0}^{k}x_i^2y_i^2 & \sum_{i=0}^{k}x_iy_i^3 & \sum_{i=0}^{k}y_i^4 & \sum_{i=0}^{k}x_iy_i^2 & \sum_{i=0}^{k}y_i^3 & \sum_{i=0}^{k}y_i^2\\ \sum_{i=0}^{k}x_i^3 & \sum_{i=0}^{k}x_i^2y_i & \sum_{i=0}^{k}x_iy_i^2 & \sum_{i=0}^{k}x_i^2 & \sum_{i=0}^{k}x_iy_i & \sum_{i=0}^{k}x_i\\ \sum_{i=0}^{k}x_i^2y_i & \sum_{i=0}^{k}x_iy_i^2 & \sum_{i=0}^{k}y_i^3 & \sum_{i=0}^{k}x_iy_i & \sum_{i=0}^{k}y_i^2 & \sum_{i=0}^{k}y_i\\ \sum_{i=0}^{k}x_i^2 & \sum_{i=0}^{k}x_iy_i & \sum_{i=0}^{k}y_i^2 & \sum_{i=0}^{k}x_i & \sum_{i=0}^{k}y_i & \sum_{i=0}^{k}1\\ \end{matrix} \right] \left[ \begin{matrix} a \\ b \\ c \\ d \\ e \\ f \\ \end{matrix} \right]= \left[ \begin{matrix} \sum_{i=0}^{k}z_ix_i^2 \\ \sum_{i=0}^{k}z_ix_iy_i \\ \sum_{i=0}^{k}z_iy_i^2 \\ \sum_{i=0}^{k}z_ix_i \\ \sum_{i=0}^{k}z_iy_i \\ \sum_{i=0}^{k}z_i \\ \end{matrix} \right]\tag{3} ​∑i=0k​xi4​∑i=0k​xi3​yi​∑i=0k​xi2​yi2​∑i=0k​xi3​∑i=0k​xi2​yi​∑i=0k​xi2​​∑i=0k​xi3​yi​∑i=0k​xi2​yi2​∑i=0k​xi​yi3​∑i=0k​xi2​yi​∑i=0k​xi​yi2​∑i=0k​xi​yi​​∑i=0k​xi2​yi​∑i=0k​xi​yi3​∑i=0k​yi4​∑i=0k​xi​yi2​∑i=0k​yi3​∑i=0k​yi2​​∑i=0k​xi3​∑i=0k​xi2​yi​∑i=0k​xi​yi2​∑i=0k​xi2​∑i=0k​xi​yi​∑i=0k​xi​​∑i=0k​xi2​yi​∑i=0k​xi​yi2​∑i=0k​yi3​∑i=0k​xi​yi​∑i=0k​yi2​∑i=0k​yi​​∑i=0k​xi2​∑i=0k​xi​yi​∑i=0k​yi2​∑i=0k​xi​∑i=0k​yi​∑i=0k​1​ ​ ​abcdef​ ​= ​∑i=0k​zi​xi2​∑i=0k​zi​xi​yi​∑i=0k​zi​yi2​∑i=0k​zi​xi​∑i=0k​zi​yi​∑i=0k​zi​​ ​(3)

2.参考文献

[1] 方程喜,隋立春,朱海雄.用于公路勘测设计的LiDAR点云抽稀算法[J].测绘通报,2017(10):58-61+88.

3.操作流程

在这里插入图片描述   输出二次曲面 a + b x + c y + d x 2 + e x y + f y 2 = 0 a+bx+cy+dx^2+exy+fy^2=0 a+bx+cy+dx2+exy+fy2=0的表达式和拟合误差RMS。经实测,CloudCompare的拟合结果偏差较大。

在这里插入图片描述

  此外,还生成了拟合曲面的mesh模型,可以用来计算点云到模型的距离。 在这里插入图片描述

4.完整操作

在这里插入图片描述

5.算法源码 ccQuadric* ccQuadric::Fit(CCLib::GenericIndexedCloudPersist *cloud, double* rms/*=0*/) { //number of points unsigned count = cloud->size(); if (count CCLib::Neighbourhood Yk(cloud); //plane equation const PointCoordinateType* theLSPlane = Yk.getLSPlane(); if (!theLSPlane) { ccLog::Warning("[ccQuadric::Fit] Not enough points to fit a quadric!"); return nullptr; } assert(Yk.getGravityCenter()); G = *Yk.getGravityCenter(); //local base N = CCVector3(theLSPlane); assert(Yk.getLSPlaneX() && Yk.getLSPlaneY()); X = *Yk.getLSPlaneX(); //main direction Y = *Yk.getLSPlaneY(); //secondary direction } //project the points in a temporary cloud ccPointCloud tempCloud("temporary"); if (!tempCloud.reserve(count)) { ccLog::Warning("[ccQuadric::Fit] Not enough memory!"); return nullptr; } cloud->placeIteratorAtBeginning(); for (unsigned k=0; k //set exact values for gravity center and plane equation //(just to be sure and to avoid re-computing them) Zk.setGravityCenter(CCVector3(0,0,0)); PointCoordinateType perfectEq[4] = { 0, 0, 1, 0 }; Zk.setLSPlane( perfectEq, CCVector3(1,0,0), CCVector3(0,1,0), CCVector3(0,0,1)); } Tuple3ub dims; const PointCoordinateType* eq = Zk.getQuadric(&dims); if (!eq) { ccLog::Warning("[ccQuadric::Fit] Failed to fit a quadric!"); return nullptr; } //we recenter the quadric object ccGLMatrix glMat(X,Y,N,G); ccBBox bb = tempCloud.getOwnBB(); CCVector2 minXY(bb.minCorner().x,bb.minCorner().y); CCVector2 maxXY(bb.maxCorner().x,bb.maxCorner().y); ccQuadric* quadric = new ccQuadric(minXY, maxXY, eq, &dims, &glMat); quadric->setMetaData(QString("Equation"),QVariant(quadric->getEquationString())); //compute rms if necessary if (rms) { const unsigned char dX = dims.x; const unsigned char dY = dims.y; //const unsigned char dZ = dims.z; *rms = 0; for (unsigned k=0; k *rms = sqrt(*rms / count); quadric->setMetaData(QString("RMS"),QVariant(*rms)); } } return quadric; } 6.相关代码

[1] PCL 最小二乘拟合二次曲面 [2] matlab 最小二乘拟合二次曲面 [3] Open3D 点云最小二乘拟合二次曲面



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有